package com.xx.happychatboot.middleware.netty.strategy.websocket;

import cn.hutool.json.JSONUtil;
import com.xx.happychatboot.base.constant.RedisConstant;
import com.xx.happychatboot.base.utils.JwtTokenUtils;
import com.xx.happychatboot.base.utils.RedisUtils;
import com.xx.happychatboot.middleware.netty.domain.enums.WebSocketTypeEnum;
import com.xx.happychatboot.middleware.netty.domain.vo.request.LoginWebSocketRequest;
import com.xx.happychatboot.middleware.netty.service.WebSocketService;
import com.xx.happychatboot.serve.user.service.ISysUserService;
import io.netty.channel.ChannelHandlerContext;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Objects;

/**
 * 登录策略
 */
@Component
public class LoginStrategy extends AbstractWebsocketStrategy {

    @Autowired
    private JwtTokenUtils jwtTokenUtils;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private WebSocketService webSocketService;

    /**
     * 获取对应的策略编码
     *
     * @return
     */
    @Override
    protected WebSocketTypeEnum getStrategyCode() {
        return WebSocketTypeEnum.LOGIN;
    }

    /**
     * 执行方法
     *
     * @param ctx
     * @param msg
     */
    @Override
    public void execute(ChannelHandlerContext ctx, String msg) {
        // 校验accessToken是否有效
        if (StringUtils.isBlank(msg)) {
            return;
        }

        LoginWebSocketRequest loginWebSocketRequest = JSONUtil.toBean(msg, LoginWebSocketRequest.class);

        if (Objects.isNull(loginWebSocketRequest) || StringUtils.isBlank(loginWebSocketRequest.getAccessToken())) {
            return;
        }

        String accessToken = loginWebSocketRequest.getAccessToken();

        try {
            // 校验 Token 是否可用, 若解析异常，针对不同异常做出不同的响应参数
            jwtTokenUtils.validateToken(accessToken);
        } catch (Exception e) {
            return;
        }

        // 从 Token 中解析出用户名
        String username = jwtTokenUtils.getUsernameByToken(accessToken);

        // 获取reids中的token
        String redisToken = RedisUtils.getStr(RedisConstant.JWT_ACCESS + username);
        if (!StringUtils.equals(redisToken, accessToken)) {
            return;
        }
        // 保存channel
        webSocketService.saveConnect(ctx.channel(), username);
    }
}
